home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / Z4Z5CP.C < prev    next >
C/C++ Source or Header  |  1993-08-09  |  6KB  |  188 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    z4z5cp.c
  5. //   Title:    ZIP+4 Engine
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //
  24. //    This module contains the compressor for the ZIP5 file.
  25. //
  26. //    The code in this module should be written entirely in C. 
  27. //    Do not use any C++ constructs.
  28. //
  29. //    This module is portable to:
  30. //        DOS 3.X+
  31. //        MS Windows 3.X+
  32. //        OS/2 2.X+
  33. //        OS/2 2.0 PM
  34. //        SCO UNIX.
  35. //
  36. //    The following compilers are supported:
  37. //        MSC 6.0A
  38. //        MSC/C++ 7.0
  39. //        Borland C++ 3.1 for DOS
  40. //        Borland C++ 1.0 for OS/2 2.X
  41. //        SCO UNIX cc
  42. //
  43. //----------------------------------------------------------------------------
  44. #include <z4.h>
  45.  
  46.  
  47. //----------------------------------------------------------------------------
  48. //    Prototypes
  49. //----------------------------------------------------------------------------
  50. static BOOL FN_L Z4Z5CompressAppend(PDATACOMP, PZ4_Z5);
  51. static RECID recid;
  52.  
  53.  
  54. //----------------------------------------------------------------------------
  55. //   Description:    Compression function    
  56. //    Parameters:    pdatacomp    Compressor data
  57. //       Returns:    Compression function result code. See data.h.
  58. //----------------------------------------------------------------------------
  59. SHORT FN_E Z4Z5Compress(PDATACOMP pdatacomp)
  60. {
  61. static BOOL fPending;                        // ZIP5 record pending?
  62. static Z4_Z5 z5;                                // ZIP5 record
  63. static LONG alZ5Count[Z4_ST_MAX];
  64. static SIZET cMaxCities;
  65. static SIZET cZip;
  66. static SIZET cPof;
  67. static SIZET cState;
  68.  
  69.     LONG lRec = pdatacomp->dlmrec.lId;
  70.     PPSZ ppsz = pdatacomp->dlmrec.apsz;
  71.     Z4_STATE state;
  72.  
  73.     switch (lRec)
  74.         {
  75.         case DAI_INITIALIZE:                    // Initialize at startup
  76.             memset(alZ5Count, 0, sizeof(alZ5Count));
  77.          cMaxCities = 0;
  78.             cZip        = DataField(pdatacomp->dlmrec.pcfg, "zipcode");
  79.             cPof        = DataField(pdatacomp->dlmrec.pcfg, "finance");
  80.             cState    = DataField(pdatacomp->dlmrec.pcfg, "state_abbrev");
  81.         case DAI_START_BLK:                    // Start block
  82.             Assert(MAX_ZIP5_CITIES <= pdatacomp->cbMax / sizeof(RECID));
  83.             fPending = FALSE;
  84.             recid.usOffset = 0;
  85.             recid.lBlock = 0;
  86.             return DAO_SUCCESS;
  87.  
  88.         case DAI_TERMINATE:                    // Terminate
  89.             if (!Z4Z5CountWrite(alZ5Count, sizeof(alZ5Count)))
  90.                 return DAO_FAILURE;
  91.             Output("\nMaximum of %u city records in a 5 digit ZIP.\n", cMaxCities);
  92.  
  93.         case DAI_FAILURE:
  94.         case DAI_END_BLK:                        // End block
  95.             return DAO_SUCCESS;
  96.  
  97.         case DAI_LAST_REC:
  98.             if (!fPending)
  99.                 return DAO_FAILURE;
  100.             Z4Z5CompressAppend(pdatacomp, &z5);
  101.             return DAO_FLUSH;
  102.         }
  103.     if (pdatacomp->dlmrec.fSkipped)
  104.         return DAO_SKIP;
  105.     if (fPending)
  106.         {
  107.         if (strcmp(z5.szZip5, ppsz[cZip]) != 0)
  108.             {
  109.             Z4Z5CompressAppend(pdatacomp, &z5);
  110.             fPending = FALSE;
  111.             return DAO_MARK_FLUSH;
  112.             }
  113.         Assert(z5.cCities < MAX_ZIP5_CITIES);
  114.         Assert(strcmp(z5.szFinance, ppsz[cPof]) == 0);
  115.         z5.arecid[z5.cCities] = pdatacomp->dlmrec.recid;
  116.         z5.cCities++;
  117.         cMaxCities = MAX(cMaxCities, z5.cCities);
  118.         return DAO_NEXT;
  119.         }
  120.     fPending = TRUE;
  121.     state = Z4FindState(ppsz[cState]);
  122.     alZ5Count[state]++;
  123.     memset(&z5, 0, sizeof(z5));
  124.     Assert(strcmp(ppsz[cZip], "00000") != 0);
  125.     strcpy(z5.szZip5, ppsz[cZip]);
  126.     strcpy(z5.szFinance, ppsz[cPof]);
  127.     z5.arecid[z5.cCities] = pdatacomp->dlmrec.recid;
  128.     z5.cCities++;
  129.     cMaxCities = MAX(cMaxCities, z5.cCities);
  130.     return DAO_NEXT;
  131. }
  132.  
  133.  
  134. //----------------------------------------------------------------------------
  135. //   Description:    Compress the current ZIP5 record
  136. //    Parameters:    pdatacomp    Compresser data
  137. //                        pz5            ZIP5 record
  138. //       Returns:    TRUE if successful.
  139. //----------------------------------------------------------------------------
  140. static BOOL FN_L Z4Z5CompressAppend(PDATACOMP pdatacomp, PZ4_Z5 pz5)
  141. {
  142.     BYTE bBuf[sizeof(RECID) * MAX_ZIP5_CITIES];
  143.     SIZET cBuf;
  144.     PBYTE pb = pdatacomp->pb;
  145.     CHAR szZip5[MAX_ZIP5+2];
  146.  
  147.     //
  148.     //    Write the ZIP. The ZIP is stored as 6 characters, with the first 
  149.     //    character always being 9. This eliminates the problem of the first
  150.     //    byte being zero and causing the expander to exit!
  151.     //
  152.     strcpy(szZip5, "9");
  153.     strcat(szZip5, pz5->szZip5);
  154.     stra2b(pb, MAX_ZIP5_BCD, szZip5, MAX_ZIP5+1);
  155.     pb += MAX_ZIP5_BCD;
  156.                                                     // Finance number
  157.     stra2b(pb, MAX_FINANCE_BCD, pz5->szFinance, MAX_FINANCE);
  158.     pb += MAX_FINANCE_BCD;
  159.                                                     // Encode record ids
  160.     if (!RecIdEncode(pz5->arecid, pz5->cCities, bBuf, sizeof(bBuf), &cBuf, &recid))
  161.         return FALSE;
  162.  
  163.     Assert(cBuf);                                // Encode buffer size
  164.     cBuf--;
  165.     *pb = (BYTE)(cBuf & 0x007F);
  166.     if (cBuf > 0x007F)
  167.         {
  168.         *pb |= 0x80;
  169.         pb++;
  170.         Assert((cBuf >> 7) < 256);
  171.         *pb = (BYTE)cBuf;
  172.         pb++;
  173.         }
  174.     else
  175.         pb++;
  176.     cBuf++;
  177.     Assert(pdatacomp->cb <= pdatacomp->cbMax);
  178.     Assert(cBuf + 10 < pdatacomp->cbMax - pdatacomp->cb);
  179.     memcpy(pb, bBuf, cBuf);                    // Copy encoded record ids to output
  180.     pb += cBuf;
  181.                                                     // Update number of bytes written
  182.     pdatacomp->cb = (SIZET)(pb - pdatacomp->pb);
  183.     return TRUE;
  184. }
  185. //----------------------------------------------------------------------------
  186. //------------------------------- End of File --------------------------------
  187. //----------------------------------------------------------------------------
  188.